package com.yc.boot.sys.business;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yc.boot.common.config.BaseRunConfig;
import com.yc.boot.common.utils.RedisUtil;
import com.yc.boot.sys.entity.SysDictionaries;
import com.yc.boot.sys.service.SysDictionariesService;
import com.yc.boot.sys.model.UserInfo;
import com.yc.boot.sys.model.find.FindDictPage;
import com.yc.boot.sys.model.save.SaveDict;
import com.yc.boot.sys.model.update.UpdateDict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.yc.boot.common.constant.RedisConstant.SYS_DICT_CACHE;


/**
 * @author 杨智杰
 * @since 2021/8/19 8:54
 */
@Service
public class SysDictionariesBusiness {

    @Resource
    private BaseRunConfig runConfig;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private SysUserBusiness sysUserBusiness;

    @Resource
    private SysDictionariesService sysDictionariesService;

    /**
     * 查询
     *
     * @param param 查询条件
     * @return 查询结果
     */
    public IPage<SysDictionaries> page(FindDictPage param) {
        return sysDictionariesService.page(new Page<>(param.getCurrent(), param.getSize()),
                new QueryWrapper<SysDictionaries>().lambda()
                        .eq(ObjectUtil.isNotNull(param.getId()), SysDictionaries::getId, param.getId())
                        .eq(StrUtil.isNotBlank(param.getBelong()), SysDictionaries::getBelong, param.getBelong())
                        .eq(ObjectUtil.isNotNull(param.getStatus()), SysDictionaries::getStatus, param.getStatus())
                        .eq(StrUtil.isNotBlank(param.getKeyword()), SysDictionaries::getKeyword, param.getKeyword())
                        .orderByAsc(SysDictionaries::getBelong, SysDictionaries::getKeyword, SysDictionaries::getSort)
                        .orderByDesc(SysDictionaries::getCreateTime));
    }

    /**
     * 新增
     *
     * @param param 新增数据
     * @return 是否成功
     */
    public Boolean save(SaveDict param) {
        UserInfo userInfo = sysUserBusiness.getUserInfo();
        SysDictionaries dict = Convert.convert(SysDictionaries.class, param);
        dict.setCreateBy(userInfo.getId());
        boolean save = sysDictionariesService.save(dict);
        runConfig.cacheBaseDict();
        return save;
    }

    /**
     * 修改
     *
     * @param param 修改数据
     * @return 是否成功
     */
    public Boolean update(UpdateDict param) {
        UserInfo userInfo = sysUserBusiness.getUserInfo();
        SysDictionaries dict = Convert.convert(SysDictionaries.class, param);
        dict.setUpdateBy(userInfo.getId());
        runConfig.cacheBaseDict();
        return sysDictionariesService.updateById(dict);
    }

    /**
     * 删除
     *
     * @param id 根据Id删除
     * @return 是否成功
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(List<Long> id) {
        UserInfo userInfo = sysUserBusiness.getUserInfo();
        boolean updateBatchById = sysDictionariesService.updateBatchById(Convert.toList(SysDictionaries.class, id.stream()
                .map(i -> new SysDictionaries().setUpdateBy(userInfo.getId()).setId(i)).collect(Collectors.toList())));
        boolean removeByIds = sysDictionariesService.removeByIds(id);
        runConfig.cacheBaseDict();
        return updateBatchById && removeByIds;
    }

    /**
     * 优先从缓存中读取，未找到就从数据库中查询后加入到缓存中
     *
     * @param belong
     * @param keyword
     * @return
     */
    public List<SysDictionaries> list(String belong, String keyword) {
        Map<String, List<SysDictionaries>> map = (Map<String, List<SysDictionaries>>) redisUtil.get(SYS_DICT_CACHE + belong);
        if (ObjectUtil.isNull(map)) {
            List<SysDictionaries> list = sysDictionariesService.list(new QueryWrapper<SysDictionaries>().lambda()
                    .eq(SysDictionaries::getBelong, belong).eq(SysDictionaries::getKeyword, keyword));
            if (CollUtil.isNotEmpty(list)) {
                map = new LinkedHashMap<>();
                map.put(keyword, list);
                redisUtil.set(SYS_DICT_CACHE + belong, map);
            }
            return list;
        }
        return map.get(keyword);
    }
}
